<template>
  <div class="video-player">
    <!-- 播放器界面; 兼容ios  controls-->
    <video
      ref="video"
      v-if="showVideo"
      webkit-playsinline="true"
      playsinline="true"
      x-webkit-airplay="true"
      x5-video-player-type="h5"
      x5-video-player-fullscreen="true"
      x5-video-orientation="portraint"
      style="object-fit:fill"
      preload="auto"
      muted="true"
      poster="http://fimage.huaxiyou.cc/3078_1618545967882.3882x2180@375w.gif"
      :src="src"
      @waiting="handleWaiting"
      @canplaythrough="state.isLoading = false"
      @playing="state.isLoading = false, state.controlBtnShow = false, state.playing=true"
      @stalled="state.isLoading = true"
      @error="handleError"
    >您的浏览器不支持HTML5</video>
    <!-- 兼容Android端层级问题, 弹出层被覆盖 -->
    <img
      v-show="!showVideo || state.isEnd"
      class="poster"
      src="http://fimage.huaxiyou.cc/3078_1618545967882.3882x2180@375w.gif"
      alt
    >
    <!-- 控制窗口 -->
    <div
      class="control"
      v-show="!state.isError"
      ref="control"
      @touchstart="touchEnterVideo"
      @touchend="touchLeaveVideo"
      @mouseover="mouseOver()" @mouseleave="mouseLeave()"
    >
      <!-- 播放 || 暂停 || 加载中-->
      <div class="play" @touchstart.stop="clickPlayBtn" v-show="state.controlBtnShow">
        <img
          v-show="!state.playing && !state.isLoading"
          src="./content_btn_play.svg"
        >
        <img
          v-show="state.playing  && !state.isLoading"
          src="./content_btn_pause.svg"
        >
        <div class="loader" v-show="state.isLoading">
          <div class="loader-inner ball-clip-rotate">
            <div></div>
          </div>
        </div>
      </div>
      <!-- 控制条 -->
      <!-- <div class="control-bar" v-show="state.controlBarShow"> -->
      <div class="control-bar" :style="{ visibility: state.controlBarShow ? 'visible' : 'hidden'}">
        <span class="time">{{video.displayTime}}</span>
        <span class="progress" ref="progress" :style="{height:isMoved?'2px':''}" :class="isMoved?'progress-move':''">
          <img
            ref="progress-btn"
            class="progress-btn ignore"
            :class="isMoved?'isMove':''"
            :style="{transform: `translate3d(${(video.progress.current<video.progress.width)?((video.progress.current<0)?0:video.progress.current):video.progress.width}px, -50%, 0)`}"
            :src="progressImg"
          >
          <!-- 视频缓存进度条 -->
          <span class="progress-loaded" :style="{ width: `${video.loaded}%`}"></span>
          <!-- 播放进度条 -->
          <span class="progress-loaded1" :style="{ width: `${(video.progress.current<video.progress.width)?video.progress.current:video.progress.width}px`}"></span>
          <!-- 设置手动移动的进度条 -->
          <span
            class="progress-move"
            @touchmove.stop.prevent="moveIng($event)"
            @touchstart.stop="moveStart($event)"
            @touchend.stop="moveEnd($event)"
          ></span>
        </span>

        <span class="total-time">{{video.totalTime}}</span>
        <span class="full-screen" @click="fullScreen">
          <img src="./content_ic_increase.svg" alt>
        </span>
      </div>
    </div>
    <!-- 错误弹窗 -->
    <div class="error" v-show="state.isError">
      <p class="lose">视频加载失败</p>
      <p class="retry" @click="retry">点击重试</p>
    </div>
  </div>
</template>
<script>
import { throttle } from "./tool";
//非拖拽进度条
import tutu from './yuan.svg'
//拖拽进度条
import hoverTutu from './yuan.svg'

const pad = val => {
  val = Math.floor(val);
  if (val < 10) {
    return "0" + val;
  }
  return val + "";
};
const timeParse = sec => {
  let min = 0;
  min = Math.floor(sec / 60);
  sec = sec - min * 60;
  return pad(min) + ":" + pad(sec);
};

export default {
  name: "t-video",
  props: {
    // src: {
    //   type: String,
    //   required: true
    // },
    showVideo: {
      // 兼容android弹出层
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      // video元素
      $video: null,
      src:'http://fvideo.oss-cn-shenzhen.aliyuncs.com/mp4/3078_1618545694734.mp4',
      // 视频容器元素
      player: {
        $player: null,
        pos: null
      },
      // progress进度条元素
      progressBar: {
        $progress: null, // 进度条DOM对象
        pos: null
      },
      progressImg:tutu,
      // video控制显示设置
      video: {
        loaded: 0, // 缓存长度
        displayTime: "00:00", // 进度时间
        totalTime: "00:00", // 总时间
        progress: {
          width: 0, // 进度条长度
          current: 0 // 进度条当前位置
        }
      },
      // 定时器
      hideTimer: null,
      // 播放状态控制
      state: {
        controlBtnShow: true, // 播放按钮
        controlBarShow: false, // 控制条
        fullScreen: false,
        playing: false,
        isLoading: false,
        isEnd: false,
        isError: false
      },
      // 首次触摸
      isFirstTouch: true,
      // 暂停状态触摸
      isPauseTouch: false,
      //收否在拖拽进度条
      isMoved:false
    };
  },

  methods: {
    init() {
      // 初始化video,获取video元素
      this.$video = this.$el.getElementsByTagName("video")[0];
      this.initPlayer();
    },
    // 初始化播放器容器, 获取video-player元素
    // getBoundingClientRect()以client可视区的左上角为基点进行位置计算
    initPlayer() {
      const $player = this.$el;
      const $progress = this.$el.getElementsByClassName("progress")[0];
      // 播放器位置
      this.player.$player = $player;
      this.progressBar.$progress = $progress;
      this.player.pos = $player.getBoundingClientRect();
      this.progressBar.pos = $progress.getBoundingClientRect()
      this.video.progress.width = Math.round($progress.getBoundingClientRect().width);
      console.log('this.video.progress.width',this.video.progress.width)
    },
    //点击controller
    clickControl(){
      this.clickPlayBtn()
    },
    mouseOver(){
      console.log('进入')
      this.state.controlBarShow = true
    },
    mouseLeave(){
      console.log('出去')
      this.state.controlBarShow = false
    },
    // 点击播放 & 暂停按钮
    clickPlayBtn() {
      if (this.state.isLoading) return;
      
      this.state.playing = !this.state.playing;
      this.state.isEnd = false;
      if (this.$video) {
        // 播放状态
        if (this.state.playing) {
          try {
            this.$video.play();
            this.isPauseTouch = false;
            // 监听缓存进度
            let that = this
            var newHandle = function (event) {
              handleAction(event)
            }
            if(!this.isFirstTouch) return
            this.$nextTick(()=>{
              this.isFirstTouch = false;
              this.$video.addEventListener("progress",this.getLoadTime,false);
              // 监听播放进度
              this.$video.addEventListener("timeupdate",throttle(this.getPlayTime, 100, 1),false);
              // 监听结束
              this.$video.addEventListener("ended", e => {
                // 重置状态
                this.state.playing = false;
                this.state.isEnd = true;
                this.state.controlBtnShow = true;
                this.video.displayTime = "00:00";
                this.video.progress.current = 0;
                this.$video.currentTime = 0;
                this.src = this.src
                this.clickPlayBtn()
              });
            })
            
          } catch (e) {
            // 捕获url异常出现的错误
          }
        }
        // 停止状态
        else {
          this.isPauseTouch = true;
          this.$video.pause();
        }
      }
    },
    // 触碰播放区
    touchEnterVideo() {
      this.clickControl()
      if (this.isFirstTouch) return;
      if (this.hideTimer) {
        clearTimeout(this.hideTimer);
        this.hideTimer = null;
      }
      this.state.controlBtnShow = true;
      this.state.controlBarShow = true;
      
    },
    // 离开播放区
    touchLeaveVideo() {
      console.log('离开播放区')
      if (this.isFirstTouch) return;
      if (this.hideTimer) {
        clearTimeout(this.hideTimer);
      }
      // 暂停触摸, 不隐藏
      if (this.isPauseTouch) {
        this.state.controlBtnShow = true;
        this.state.controlBarShow = true;
      } else {
        this.hideTimer = setTimeout(() => {
          this.state.controlBarShow = false;
          // 加载中只显示loading
          if (this.state.isLoading) {
            this.state.controlBtnShow = true;
          } else {
            this.state.controlBtnShow = false;
          }
          this.hideTimer = null;
        }, 3000);
      }
    },
    // 等待数据加载
    handleWaiting() {
      this.state.controlBtnShow = true;
      this.state.isLoading = true;
    },
    // 数据加载出错
    handleError() {
      this.state.isError = true;
    },
    // 点击重新加载
    retry() {
      this.state.isError = false;
      this.init();
    },
    // 获取播放时间
    getPlayTime() {
      const percent = this.$video.currentTime / this.$video.duration;
      this.video.progress.current = Math.round(
        this.video.progress.width * percent
      );
      console.log('progress.current',this.video.progress.current)
      // 赋值时长
      this.video.totalTime = timeParse(this.$video.duration);
      this.video.displayTime = timeParse(this.$video.currentTime);
    },
    // 获取缓存时间
    getLoadTime() {
      // console.log('缓存了...',this.$video.buffered.end(0));
      this.video.loaded =
        (this.$video.buffered.end(0) / this.$video.duration) * 100;
    },
    // 手动调节播放进度
    moveStart(e) {
      console.log('run run run')
      this.isMoved = true
      this.progressImg = hoverTutu
    },
    moveIng(e) {
      console.log("触摸中...");
      this.state.controlBarShow = true
      let currentX = e.targetTouches[0].pageX;
      let offsetX = currentX - this.progressBar.pos.left;
      // 边界检测
      if (offsetX <= 0) {
        offsetX = 0
      }
      if (offsetX >= this.video.progress.width) {
        offsetX = this.video.progress.width
      }
      this.video.progress.current = offsetX;
      
      let percent = this.video.progress.current / this.video.progress.width;
      this.$video.duration && this.setPlayTime(percent, this.$video.duration)
    },
    moveEnd(e) {
      // console.log("触摸结束...");
      let currentX = e.changedTouches[0].pageX;
      let offsetX = currentX - this.progressBar.pos.left;
      this.video.progress.current = offsetX;
      // 这里的offsetX都是正数
      let percent = offsetX / this.video.progress.width;
      this.$video.duration && this.setPlayTime(percent, this.$video.duration)
      this.progressImg = tutu
      this.isMoved = false
    },
    // 设置手动播放时间
    setPlayTime(percent, totalTime) {
      this.$video.currentTime = Math.floor(percent * totalTime);
    },
    // 设置全屏
    fullScreen() {
      console.log('点击全屏...');
      if (!this.state.fullScreen) {
        this.state.fullScreen = true;
        this.$video.webkitRequestFullScreen();
      } else {
        this.state.fullScreen = false;
        document.webkitCancelFullScreen();
      }
    },
  },
  mounted() {
    setTimeout(() => {
      this.init();
    }, 20);
  },
  beforeDestroy() {}
};
</script>
<style lang='less' scoped>
@keyframes rotate {
  0% {
    transform: rotate(0deg);
  }
  50% {
    transform: rotate(180deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.loader {
  width: 58px;
  height: 58px;
  background: rgba(15, 16, 17, 0.3);
  border-radius: 50%;
  position: relative;
  .ball-clip-rotate {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    > div {
      width: 15px;
      height: 15px;
      border-radius: 100%;
      margin: 2px;
      animation-fill-mode: both;

      border: 2px solid #fff;
      border-bottom-color: transparent;
      height: 26px;
      width: 26px;
      background: transparent !important;
      display: inline-block;
      animation: rotate 0.75s 0s linear infinite;
    }
  }
}

.video-player {
  width: 100%;
  height: 188px;
  overflow: hidden;
  position: relative;
  // .control-bar{
  //   visibility:hidden
  // }
  // :hover .control-bar{
  //   visibility:visible!important
  // }
  // 封面
  .poster {
    position: absolute;
    z-index: 1;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
  }
  video {
    border-radius: 10px 10px 0 0;
    width: 100%;
    height: 100%;
  }
  // 控制层
  .control {
    width: 100%;
    height: 100%;
    position: absolute;
    z-index: 2;
    left: 0;
    top: 0;
    background-color: transparent;
    // background: #000;

    .play {
      width: 58px;
      height: 58px;
      position: absolute;
      z-index: 3;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      img {
        width: 100%;
        height: 100%;
      }
    }
    &-bar {
      position: absolute;
      bottom: 8px;
      left: 50%;
      transform: translateX(-50%);
      height: 26px;
      display: flex;
      align-items: center;
      span {
        font-size: 12px;
        color: #fff;
        font-weight: 500;
        white-space: nowrap;
      }

      .progress {
        position: relative;
        margin: 0 8px;
        width: 203px;
        max-width: 203px;
        height: 2px;
        background: rgba(255, 255, 255, 0.4);
        border-radius: 2px;
        position: relative;
        .progress-move {
          width: 100%;
          height: 26px;
          position: absolute;
          z-index: 100;
          left: 0;
          top: 0;
          transform: translateY(-50%);
          background-color: transparent;
        }
        .progress-btn {
          position: absolute;
          left: -10px;
          top: 50%;
          transition: all 16ms;
        }
        // 不会被转义
        .ignore {
            width: 11px;
            height: 11px;
            z-index: 100;
            border-radius: 50%;
            &.isMove{
              border: 5px solid rgba(255, 255, 255, 0.2);
              // top: -9px;
            }
            
        }
        .progress-loaded {
          background-color: #fff;
          position: absolute;
          left: 0;
          top: 0;
          width: 0;
          height: 100%;
          border-radius: 2px;
          transition: all 16ms;
        }
        .progress-loaded1 {
          background-color: red;
          position: absolute;
          left: 0;
          top: 0;
          width: 0;
          height: 100%;
          border-radius: 2px;
          transition: all 16ms;
        }
        &.progress-move{
          .progress-loaded{
            top: -1px;
            height: 4px;
          }
          .progress-loaded1{
            top: -1px;
            height: 4px;
          }
        }
      }
      .full-screen {
        width: 26px;
        height: 26px;
        margin-left: 8px;
        img {
          width: 100%;
          height: 100%;
        }
      }
    }
  }
  // 错误层
  .error {
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.84);
    position: absolute;
    left: 0;
    top: 0;
    z-index: 2;
    .lose {
      text-align: center;
      font-size: 15px;
      font-weight: 500;
      color: rgba(255, 255, 255, 1);
      line-height: 23px;
      margin-top: 63px;
      margin-bottom: 40px;
    }
    .retry {
      margin: 0 auto;
      text-align: center;
      line-height: 38px;
      width: 101px;
      height: 38px;
      background: rgba(255, 255, 255, 1);
      border-radius: 19px;
      font-size: 15px;
      color: #008eff;
    }
  }
}
</style>